package db

import (
	"database/sql"
	"log"
	"os"
	"time"

	"github.com/LyricTian/retry"
	"gopkg.in/gorp.v2"

	// 引入mysql驱动
	_ "github.com/go-sql-driver/mysql"
)

// NewMySQL 创建MySQL数据库实例
func NewMySQL(opts ...Option) (*DB, error) {
	o := &options{
		maxLifetime:  time.Hour * 2,
		maxOpenConns: 150,
		maxIdleConns: 50,
	}

	for _, opt := range opts {
		opt(o)
	}

	m := &DB{opts: o, log: log.New(os.Stderr, "", log.LstdFlags)}

	db, err := sql.Open("mysql", m.opts.dsn)
	if err != nil {
		return nil, err
	}

	// 尝试发送Ping包
	err = retry.DoFunc(10, func() error {
		perr := db.Ping()
		if perr != nil {
			m.log.Printf("发送ping值错误：%s", perr.Error())
		}
		return perr
	}, func(i int) time.Duration {
		m.log.Printf("尝试发送第[%d]次ping包...", i)
		return time.Second * 5 * time.Duration(i)
	})
	if err != nil {
		return nil, err
	}

	db.SetMaxOpenConns(m.opts.maxOpenConns)
	db.SetMaxIdleConns(m.opts.maxIdleConns)
	db.SetConnMaxLifetime(m.opts.maxLifetime)

	m.DbMap = &gorp.DbMap{Db: db, Dialect: gorp.MySQLDialect{Encoding: "UTF8", Engine: "InnoDB"}}

	if m.opts.trace && m.log != nil {
		m.TraceOn("[mysql]", m.log)
	}

	return m, nil
}
